/*
 * Created: 2022-08-11 13:43:05
 * Author : 涛涛涛
 */

//------------------------- 测试数据 开始 ----------------------------
/** 状态 */
type State = {
    /** 菜品名称 */
    name: string;
    /** 菜品数量 */
    count: number;
};
/** 处理的状态的方法 */
const handleMethodMapper = {
    // 增加份数
    increase: (state: State, payload: { num: number }) => {
        let newState = { ...state };
        if (!payload.num) newState.count += 1;
        else newState.count += payload.num;
        return newState;
    },
    // 设置菜品名称和份数
    setDish: (state: State, payload: Partial<State>) => {
        return {
            ...state,
            ...payload,
        };
    },
};
/** 链接状态与处理函数的方法,用于创建store */
const reducer = (state: State, action: any) => {
    let { type, payload } = action;
    if ((handleMethodMapper as any)[type]) {
        return (handleMethodMapper as any)[type](state, { ...payload });
    }
    return { ...state };
};
//------------------------- 测试数据 结束 ----------------------------

//----------------------------- 类型推断部分 开始 ------------------------
/** reducer方法印射对象
 * 任意键值对对象,该对象的值,必须是一个函数.
 */
type ReducerMapper = { [key in any]: (...pamras: any) => any };

type dddd = Parameters<(name: string, age: number) => void>;

/** 取得处理方法中Payload的mapper
 * [state:State,payload:{num:number}]; //Parameters<T[P]>
 * payload:{num:number} //Parameters<T[P]>[1]
 */
type GetPayloadMapper<T extends ReducerMapper> = {
    [Key in keyof T]: Parameters<T[Key]>[1];
};
type 例_GetPayloadMapper = GetPayloadMapper<typeof handleMethodMapper>;

/** 取得一个Actio,这里必须传入两个值,Type必须定义成泛型. */
type GetActionOne<Type extends keyof ReducerMapper, Mapper extends GetPayloadMapper<ReducerMapper>> = {
    /** 命令类型 */
    type: Type;
    /** 入参值 */
    payload?: Mapper[Type];
};

type 例_GetActionOne = GetActionOne<'setDish', 例_GetPayloadMapper>;

/** 生成 */
export type GenerateActions<Mapper extends ReducerMapper> = {
    [P in keyof Mapper]: GetActionOne<P, GetPayloadMapper<Mapper>>;
}[keyof Mapper];
